<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Time Measurement</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="kvaser.gif"/></td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('page_user_guide_time.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">Time Measurement </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#section_user_guide_time_accuracy_and_resolution_accuracy">Accuracy</a></li>
<li class="level1"><a href="#section_user_guide_time_accuracy_and_resolution_resolution">Resolution</a></li>
<li class="level1"><a href="#section_user_guide_time_domain">Time Domain</a></li>
</ul>
</div>
<div class="textblock"><p>CAN messages are time stamped as they arrive. This time stamping is, depending on your hardware platform, done either by the CAN interface hardware or by CANlib.</p>
<p>In the former case, the <b>accuracy</b> is pretty good, in the order of 1 - 10 microseconds; when CANlib does the job, the accuracy is more like 100 microseconds to 10 milliseconds and you may experience a rather large jitter. This is because Windows is not a real-time operating system.</p>
<p>The <b>resolution</b> of the time stamps is, by default, 1 ms. It can be changed to a better resolution if desired.</p>
<p>Use <a class="el" href="canlib_8h.html#a04c2f80a23b992bf17591749192e8d48">canReadTimer()</a> to read the current time. You must pass the handle of an open channel to this API call; the return value is the current time using the clock of that channel.</p>
<p>Use <a class="el" href="group__can__general.html#gaeaa24db97af22478ca51d48636c7bb12">canIoCtl()</a> with a function code of <a class="el" href="canlib_8h.html#a5b5d43fc8968aa77e48ef8c8d3036c36">canIOCTL_SET_TIMER_SCALE</a> to change the resolution of the time stamps, if desired. This will not affect the accuracy of the time stamps.</p>
<h1><a class="anchor" id="section_user_guide_time_accuracy_and_resolution_accuracy"></a>
Accuracy</h1>
<p>The accuracy of the time stamps depends on the hardware.</p>
<p>The members of the Kvaser Leaf family have an onboard CPU. The time stamp accuracy varies (check the hardware manual) but the high-end members have very precise time stamping. The accuracy can be as good as one microsecond depending on the hardware. If more than one Leaf is used, their clocks are automatically kept in sync by the Kvaser MagiSync&trade; technology.</p>
<p>Other CAN interfaces, like the Kvaser Leaf, LAPcan and USBcan II, have an on-board CPU and clock and provide very accurate time stamps for incoming CAN messages. The accuracy is typically 10-20 microseconds.</p>
<p>Certain interfaces, like the PCIcan (PCI) series of boards, don't have an on-board CPU so the driver relies on the clock in the PC to timestamp the incoming messages. As Windows is not a real-time operating system, this gives an accuracy which is in the order of one millisecond.</p>
<h1><a class="anchor" id="section_user_guide_time_accuracy_and_resolution_resolution"></a>
Resolution</h1>
<p>The resolution of the time stamps is, by default, 1 ms. It can be changed by calling <a class="el" href="group__can__general.html#gaeaa24db97af22478ca51d48636c7bb12">canIoCtl()</a> with the <a class="el" href="canlib_8h.html#a5b5d43fc8968aa77e48ef8c8d3036c36">canIOCTL_SET_TIMER_SCALE</a> function code.</p>
<h1><a class="anchor" id="section_user_guide_time_domain"></a>
Time Domain</h1>
<p>The time domain is a system to group a set of devices to a common time which can be useful for time synchronised applications between multiple devices.</p>
<p>While all kvaser devices supports the use of time domains they can get out of sync over time, to avoid this some devices have support for MagiSync™ which will continuously apply an offset to their clocks to compensate for any drifting that may occur.</p>
<p>After creating a time domain and adding handles to it, use <a class="el" href="group___time_domain_handling.html#gaf1857d6195e783c082b44a6e6cf9f745">kvTimeDomainResetTime()</a> to reset the time of the domain.</p>
<dl class="section note"><dt>Note</dt><dd>For the time domain to function properly all devices that are part of it should be connected to the same root usb hub.</dd></dl>
<ul>
<li><a class="el" href="group___time_domain_handling.html#gaef2b34a7cd8ab01fc140aabe3a5f5539">kvTimeDomainCreate()</a></li>
<li><a class="el" href="group___time_domain_handling.html#gaf42198d9685ffc7094fc4cd276ab1976">kvTimeDomainDelete()</a></li>
<li><a class="el" href="group___time_domain_handling.html#gaf1857d6195e783c082b44a6e6cf9f745">kvTimeDomainResetTime()</a></li>
<li><a class="el" href="group___time_domain_handling.html#gafab02cbe0c7fd8cfa65382d492d724b9">kvTimeDomainGetData()</a></li>
<li><a class="el" href="group___time_domain_handling.html#ga73890ef75367c8536235bcc5a6370b26">kvTimeDomainAddHandle()</a></li>
<li><a class="el" href="group___time_domain_handling.html#gad9f730b78a8755e4ec915f75d47e2c79">kvTimeDomainRemoveHandle()</a></li>
</ul>
<p><b>Example</b>. The following code fragment resets the time for some already opened channels. It also collects and interprets some data from a domain.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#define NUMBER_OF_CHANNELS 3</span></div><div class="line"><a class="code" href="canlib_8h.html#a75f2e3a4c7b1e47c8c6b25b76975b510">CanHandle</a> hnd[NUMBER_OF_CHANNELS];</div><div class="line"><a class="code" href="canstat_8h.html#a52b5e5c71832b0bd3c6a5b1fd48583e7">canStatus</a> stat;</div><div class="line"><span class="keywordtype">int</span> i;</div><div class="line"><a class="code" href="canlib_8h.html#a48bb105cf654887225e6c1eadb144314">kvTimeDomain</a> tDomain;</div><div class="line"><a class="code" href="structkv_time_domain_data__s.html">kvTimeDomainData</a> tData;</div><div class="line"></div><div class="line">...</div><div class="line"></div><div class="line"><span class="comment">// Create a time domain for my handles.</span></div><div class="line">stat = <a class="code" href="group___time_domain_handling.html#gaef2b34a7cd8ab01fc140aabe3a5f5539">kvTimeDomainCreate</a>(&amp;tDomain);</div><div class="line"><span class="keywordflow">if</span> (stat &lt; 0) {</div><div class="line">    printf(<span class="stringliteral">&quot;Failed, status == %d\n&quot;</span>, stat);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Add the handles to the domain.</span></div><div class="line"><span class="keywordflow">for</span> (i = 0; i &lt; NUMBER_OF_CHANNELS; i++) {</div><div class="line">  stat = <a class="code" href="group___time_domain_handling.html#ga73890ef75367c8536235bcc5a6370b26">kvTimeDomainAddHandle</a>(tDomain, hnd[i]);</div><div class="line">  <span class="keywordflow">if</span> (stat &lt; 0) {</div><div class="line">      printf(<span class="stringliteral">&quot;Failed to add handle %u to tDomain, &quot;</span>, i);</div><div class="line">      printf(<span class="stringliteral">&quot;status == %d\n&quot;</span>, stat);</div><div class="line">  }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Request some data from the domain and try to interpret it.</span></div><div class="line">stat = <a class="code" href="group___time_domain_handling.html#gafab02cbe0c7fd8cfa65382d492d724b9">kvTimeDomainGetData</a>(tDomain, &amp;tData; <span class="keyword">sizeof</span>(tData));</div><div class="line"><span class="keywordflow">if</span> (stat &lt; 0) {</div><div class="line">    printf(<span class="stringliteral">&quot;Failed, status == %d\n&quot;</span>, stat);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (tData.<a class="code" href="structkv_time_domain_data__s.html#ab8dca255d18320cb7bd22b0448d78fb7">nMagiSyncGroups</a> &gt; 1) {</div><div class="line">  printf(<span class="stringliteral">&quot;Consider connecting the Kvaser MagiSync&amp;tm; enabled &quot;</span>);</div><div class="line">  printf(<span class="stringliteral">&quot;interfaces through the same USB root hub!&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (tData.<a class="code" href="structkv_time_domain_data__s.html#ab8dca255d18320cb7bd22b0448d78fb7">nMagiSyncGroups</a> == 1) {</div><div class="line">  printf(<span class="stringliteral">&quot;All my Kvaser MagiSync&amp;tm; enabled interfaces are &quot;</span>);</div><div class="line">  printf(<span class="stringliteral">&quot;connected through the same USB root hub and hence &quot;</span>);</div><div class="line">  printf(<span class="stringliteral">&quot;perfectly synchronized!&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (tData.<a class="code" href="structkv_time_domain_data__s.html#aadd2929832bd903c78ddf59c21feea05">nMagiSyncedMembers</a> == NUMBER_OF_CHANNELS) {</div><div class="line">  printf(<span class="stringliteral">&quot;All handles have the Kvaser MagiSync&amp;tm; feature enabled!&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Reset the time on all handles in tDomain.</span></div><div class="line">stat = <a class="code" href="group___time_domain_handling.html#gaf1857d6195e783c082b44a6e6cf9f745">kvTimeDomainResetTime</a>(tDomain);</div><div class="line"><span class="keywordflow">if</span> (stat &lt; 0) {</div><div class="line">  printf(<span class="stringliteral">&quot;Failed, status == %d\n&quot;</span>, stat);</div><div class="line">}</div><div class="line"></div><div class="line">...</div><div class="line"></div><div class="line"><span class="comment">// Final cleanup</span></div><div class="line">stat = <a class="code" href="group___time_domain_handling.html#gaf42198d9685ffc7094fc4cd276ab1976">kvTimeDomainDelete</a>(tDomain);</div><div class="line"><span class="keywordflow">if</span> (stat &lt; 0) {</div><div class="line">  printf(<span class="stringliteral">&quot;Failed, status == %d\n&quot;</span>, stat);</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span> {</div><div class="line">  printf(<span class="stringliteral">&quot;All resources used by tDomain and its members &quot;</span>);</div><div class="line">  printf(<span class="stringliteral">&quot;returned to system&quot;</span>);</div><div class="line">}</div></div><!-- fragment --> </div></div><!-- contents -->
</div><!-- doc-content -->
<!-- HTML footer for doxygen 1.8.13-->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="navelem"><a class="el" href="page_canlib.html">CAN bus API (CANlib)</a></li>
    <li class="footer"> (canlib 5.38) Tue Feb 15 2022</li>
  </ul>
</div>
</body>
</html>
